package com.hoodemia.core;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

import javax.microedition.io.Connector;
import javax.microedition.io.SecureConnection;
import javax.microedition.io.StreamConnection;

import org.kxml2.io.KXmlParser;
import org.kxml2.io.KXmlSerializer;
import org.xmlpull.v1.XmlPullParser;

import com.Localytics.LocalyticsSession.UploaderThread;

import net.rim.device.api.io.transport.ConnectionDescriptor;
import net.rim.device.api.io.transport.ConnectionFactory;
import net.rim.device.api.servicebook.ServiceBook;
import net.rim.device.api.servicebook.ServiceRecord;
import net.rim.device.api.system.CoverageInfo;
import net.rim.device.api.system.DeviceInfo;
import net.rim.device.api.system.WLANInfo;
import net.sourceforge.jxa.XmlReader;
import net.sourceforge.jxa.XmlWriter;

public class RegisterAccount extends Thread {
	
	boolean use_ssl = false;
	String port = "5222";
	String server = "hoodemia.com";
	String connectionMask = getConnectionString(); 
	XmlReader reader;
	XmlWriter writer;
	InputStream is;
	OutputStream os;
	
	public void run() {
		/*ConnectionFactory connFact = new ConnectionFactory();
		connFact.setConnectionMode(ConnectionFactory.ACCESS_READ_WRITE);
		connFact.setAttemptsLimit(5);
		connFact.setTimeoutSupported(true);
		connFact.setConnectionTimeout(10000);
		connFact.setRetryFactor(500);
		ConnectionDescriptor connDesc = connFact.getConnection("ssl://" + this.server + ":" + this.port + this.connectionMask);
		
		StreamConnection connection = null;
		KXmlParser xmlParser = null;
		KXmlSerializer xmlSerializer = null;*/
//		if(!connDesc.equals(null)) {
			try {
				if (!use_ssl) {
					final StreamConnection connection = (StreamConnection) Connector
							.open("socket://" + this.server + ":" + this.port
									+ this.connectionMask, Connector.READ_WRITE);
//					connection = (StreamConnection) connDesc.getConnection();
					
					/*xmlParser = new KXmlParser();
					xmlSerializer = new KXmlSerializer();
					
					xmlParser.setInput(new InputStreamReader(connection.openInputStream()));
//					xmlParser.require(XmlPullParser.START_TAG, null, "stream:stream");
					xmlSerializer.setOutput(new OutputStreamWriter(connection.openOutputStream()));*/
					
					is = connection.openInputStream();
					os = connection.openOutputStream();
					
//					this.reader = new XmlReader(connection.openInputStream());
//					this.writer = new XmlWriter(connection.openOutputStream());
					this.reader = new XmlReader(is);
					this.writer = new XmlWriter(os);
				} else {
					final SecureConnection sc = (SecureConnection) Connector
							.open("ssl://" + this.server + ":" + this.port
									+ this.connectionMask, Connector.READ_WRITE);
					// sc.setSocketOption(SocketConnection.DELAY, 1);
					// sc.setSocketOption(SocketConnection.LINGER, 0);
					is = sc.openInputStream();
					os = sc.openOutputStream();
					this.reader = new XmlReader(is);
					this.writer = new XmlWriter(os);
				}
			} catch (final Exception e) {
				e.printStackTrace();
				return;
			}
//		}
		
		java.lang.System.out.println(use_ssl?"Connected with SSL":"Connected without SSL");
		
		// connected
		try {
			if(!use_ssl) {
				/*this.writer.startTag("stream:stream");
				this.writer.attribute("to", this.server);
				this.writer.attribute("xmlns", "jabber:client");
				this.writer.attribute("xmlns:stream", "http://etherx.jabber.org/streams");
				this.writer.flush();
				
				// ====
				
				this.writer.startTag("iq");
				this.writer.attribute("type", "set");
				this.writer.attribute("id", "register");
				this.writer.attribute("to", this.server);
				this.writer.startTag("query");
				this.writer.attribute("xmlns", "jabber:iq:register");

				this.writer.startTag("x");
				this.writer.attribute("xmlns", "jabber:x:data");
				this.writer.attribute("type", "form");
				
				// =====
				
				this.writer.startTag("field");
				this.writer.attribute("var", "FORM_TYPE");
				this.writer.attribute("type", "hidden");
				this.writer.startTag("value");
				this.writer.text("jabber:iq:register");
				this.writer.endTag();
				this.writer.endTag();
				
				this.writer.startTag("field");
				this.writer.attribute("var", "username");
				this.writer.attribute("type", "text-single");
				this.writer.attribute("label", "Username");
				this.writer.startTag("value");
				this.writer.text("chuck");
				this.writer.endTag();
				this.writer.endTag();
				
				this.writer.startTag("field");
				this.writer.attribute("var", "name");
				this.writer.attribute("type", "text-single");
				this.writer.attribute("label", "Full Name");
				this.writer.startTag("value");
				this.writer.text("Chuck Norris");
				this.writer.endTag();
				this.writer.endTag();
				
				this.writer.startTag("field");
				this.writer.attribute("var", "email");
				this.writer.attribute("type", "text-single");
				this.writer.attribute("label", "Email");
				this.writer.startTag("value");
				this.writer.text("chuck@norris.net");
				this.writer.endTag();
				this.writer.endTag();
				
				this.writer.startTag("field");
				this.writer.attribute("var", "password");
				this.writer.attribute("type", "text-private");
				this.writer.attribute("label", "Password");
				this.writer.startTag("value");
				this.writer.text("44d47a4076934eb45e33b257cb3c17dd");
				this.writer.endTag();
				this.writer.endTag();
				
				// ====
				
				this.writer.endTag();
				this.writer.endTag();
				this.writer.endTag();
				this.writer.flush();*/
				
				// WADUH
				
				/*xmlSerializer.startTag("", "stream:stream");
				xmlSerializer.attribute("", "to", this.server);
				xmlSerializer.attribute("", "xmlns", "jabber:client");
				xmlSerializer.attribute("", "xmlns:stream", "http://etherx.jabber.org/streams");
				xmlSerializer.flush();
				
				xmlSerializer.startTag("", "iq");
				xmlSerializer.attribute("", "type", "set");
				xmlSerializer.attribute("", "id", "auth");
				xmlSerializer.startTag("", "query");
				xmlSerializer.attribute("", "xmlns", "jabber:iq:auth");
				
				xmlSerializer.startTag("", "username");
				xmlSerializer.text("fahri");
				xmlSerializer.endTag("", "username");
				xmlSerializer.startTag("", "password");
				xmlSerializer.text("fbffacc49827d260258d90624d4526eb");
				xmlSerializer.endTag("", "password");
				xmlSerializer.startTag("", "resource");
				xmlSerializer.text("bbbapakmu");
				xmlSerializer.endTag("", "resource");
				
				xmlSerializer.endTag("", "query");
				xmlSerializer.endTag("", "iq");
				xmlSerializer.flush();
				
				xmlSerializer.startTag("", "message");
				xmlSerializer.attribute("", "type", "chat");
				xmlSerializer.attribute("", "to", "arsyady@hoodemia.com");
				xmlSerializer.startTag("", "body");
				xmlSerializer.text("Si doel anak betawi asli");
				xmlSerializer.attribute("", "type", "chat");
				xmlSerializer.endTag("", "body");
				xmlSerializer.endTag("", "message");
				xmlSerializer.flush();*/
				
				// via direct output/input stream
				/*String msg = "<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='" +this.server+ "' version='1.0'>";
				os.write(msg.getBytes());
				os.flush();*/
				
				/*msg = "<iq type='set' id='auth'>" +
						"<query xmlns='jabber:iq:auth'>" +
						"<username>fahri</username>" +
						"<password>fbffacc49827d260258d90624d4526eb</password>" +
						"<resource>mac</resource>" +
						"</query></iq>";
				os.write(msg.getBytes());
				os.flush();
				
				msg = "<message type='chat' to='arsyady@hoodemia.com'>"
						+ "<body>aduh, sialan. si si doel anak betawi asli</body>"
						+ "</message>";
				os.write(msg.getBytes());
				os.flush();
				
				msg = "</stream:stream>";
				os.write(msg.getBytes());
				os.flush();*/
				
//				System.out.println(this.parseText());
				
				// initiate stream and login
				this.writer.startTag("stream:stream");
				this.writer.attribute("to", this.server);
				this.writer.attribute("xmlns", "jabber:client");
				this.writer.attribute("xmlns:stream", "http://etherx.jabber.org/streams");
				this.writer.flush();
				
				this.writer.startTag("iq");
				this.writer.attribute("type", "set");
				this.writer.attribute("id", "auth");
				this.writer.startTag("query");
				this.writer.attribute("xmlns", "jabber:iq:auth");

				this.writer.startTag("username");
				this.writer.text("fahri");
				this.writer.endTag();
				this.writer.startTag("password");
				this.writer.text("fbffacc49827d260258d90624d4526eb");
				this.writer.endTag();
				this.writer.startTag("resource");
				this.writer.text("bbbapakmu");
				this.writer.endTag();

				this.writer.endTag(); // query
				this.writer.endTag(); // iq
				this.writer.flush();
				
				/*this.writer.startTag("message");
				this.writer.attribute("type", "chat");
				this.writer.attribute("to", "arsyady@hoodemia.com");
				this.writer.startTag("body");
				this.writer.text("Si doel emang anak betawi asli");
				this.writer.endTag();
				this.writer.endTag();
				this.writer.flush();
				
				this.writer.endTag();
				this.writer.flush();*/
			}
		} catch (Exception e) {
			e.printStackTrace();
		}/* finally {
//			String xmlStr = xmlParser.getText();
//			System.out.println(xmlStr);
//			System.out.println("depth: " + xmlParser.getDepth());
			
			try {
				this.reader.parseHtml();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}*/

		System.out.println("[ERROR] SHOULDN'T RETURN TO HERE");
	}
	
	public String getText() {
		try {
			return this.parseText();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return "XML error gan!";
		}
	}
	
	private String parseText() throws IOException {
		final String endTagName = this.reader.getName();
		final StringBuffer str = new StringBuffer("");
		int t = this.reader.next(); // omit start tag
		while (!endTagName.equals(this.reader.getName())) {
			if (t == XmlReader.TEXT) {
				str.append(this.reader.getText());
			}
			t = this.reader.next();
		}
		return str.toString();
	}

	public String getRandomTag() {
		try {
			this.reader.next();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return this.reader.getName();
	}
	
	public void logoff() {
		try {
			this.writer.endTag();
			this.writer.flush();
			/*String msg = "</stream:stream>";
			os.write(msg.getBytes());
			os.flush();*/
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void login() {
		try {
			/*this.writer.startTag("iq");
			this.writer.attribute("type", "set");
			this.writer.attribute("id", "auth");
			this.writer.startTag("query");
			this.writer.attribute("xmlns", "jabber:iq:auth");
			
			this.writer.startTag("username");
			this.writer.text("fahri");
			this.writer.endTag();
			this.writer.startTag("password");
			this.writer.text("fbffacc49827d260258d90624d4526eb");
			this.writer.endTag();
			this.writer.startTag("resource");
			this.writer.text("bbbapakmu");
			this.writer.endTag();

			this.writer.endTag(); // query
			this.writer.endTag(); // iq
			this.writer.flush();*/
			
			/*String msg = "<iq type='set' id='auth'>"
					+ "<query xmlns='jabber:iq:auth'>"
					+ "<username>fahri</username>"
					+ "<password>fbffacc49827d260258d90624d4526eb</password>"
					+ "<resource>mac</resource>" + "</query></iq>";*/
			String msg = "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>ZmFocmlAaG9vZGVtaWEuY29tAGZhaHJpAGZiZmZhY2M0OTgyN2QyNjAyNThkOTA2MjRkNDUyNmVi</auth>";
			os.write(msg.getBytes());
			os.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void sendFixedMessage() {
		try {
			this.writer.startTag("stream:stream");
			this.writer.attribute("to", this.server);
			this.writer.attribute("xmlns", "jabber:client");
			this.writer.attribute("xmlns:stream", "http://etherx.jabber.org/streams");
			this.writer.flush();
			
			this.writer.startTag("message");
			this.writer.attribute("type", "chat");
			this.writer.attribute("to", "arsyady@hoodemia.com");
			this.writer.startTag("body");
			this.writer.text("Si doel emang anak betawi asli");
			this.writer.endTag();
			this.writer.endTag();
			this.writer.flush();
			
			this.writer.endTag();
			this.writer.flush();
			
			/*String msg = "<message type='chat' to='arsyady@hoodemia.com'>" +
					"<body>aduh, sialan. si si doel anak betawi asli</body>" +
					"</message>";
			os.write(msg.getBytes());
			os.flush();*/
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static String getConnectionString() {
		// This code is based on the connection code developed by Mike Nelson of
		// AccelGolf.
		// http://blog.accelgolf.com/2009/05/22/blackberry-cross-carrier-and-cross-network-http-connection
		String connectionString = null;

		// Simulator behavior is controlled by the USE_MDS_IN_SIMULATOR
		// variable.
		if (DeviceInfo.isSimulator()) {
			if (UploaderThread.USE_MDS_IN_SIMULATOR) {
				UploaderThread
						.logMessage("Device is a simulator and USE_MDS_IN_SIMULATOR is true");
				connectionString = ";deviceside=false";
			} else {
				UploaderThread
						.logMessage("Device is a simulator and USE_MDS_IN_SIMULATOR is false");
				connectionString = ";deviceside=true";
			}
		}

		// Wifi is the preferred transmission method
		else if (WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED) {
			UploaderThread.logMessage("Device is connected via Wifi.");
			connectionString = ";interface=wifi";
		}

		// Is the carrier network the only way to connect?
		else if ((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_DIRECT) == CoverageInfo.COVERAGE_DIRECT) {
			UploaderThread.logMessage("Carrier coverage.");

			String carrierUid = getCarrierBIBSUid();
			if (carrierUid == null) {
				// Has carrier coverage, but not BIBS. So use the carrier's TCP
				// network
				UploaderThread.logMessage("No Uid");
				connectionString = ";deviceside=true";
			} else {
				// otherwise, use the Uid to construct a valid carrier BIBS
				// request
				UploaderThread.logMessage("uid is: " + carrierUid);
				connectionString = ";deviceside=false;connectionUID="
						+ carrierUid + ";ConnectionType=mds-public";
			}
		}

		// Check for an MDS connection instead (BlackBerry Enterprise Server)
		else if ((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_MDS) == CoverageInfo.COVERAGE_MDS) {
			UploaderThread.logMessage("MDS coverage found");
			connectionString = ";deviceside=false";
		}

		// If there is no connection available abort to avoid bugging the user
		// unnecssarily.
		else if (CoverageInfo.getCoverageStatus() == CoverageInfo.COVERAGE_NONE) {
			UploaderThread.logMessage("There is no available connection.");
		}

		// In theory, all bases are covered so this shouldn't be reachable.
		else {
			UploaderThread
					.logMessage("no other options found, assuming device.");
			connectionString = ";deviceside=true";
		}

		return connectionString;
	}
	private static String getCarrierBIBSUid() {
		ServiceRecord[] records = ServiceBook.getSB().getRecords();
		int currentRecord;

		for (currentRecord = 0; currentRecord < records.length; currentRecord++) {
			if (records[currentRecord].getCid().toLowerCase().equals("ippp")) {
				if (records[currentRecord].getName().toLowerCase().indexOf(
						"bibs") >= 0) {
					return records[currentRecord].getUid();
				}
			}
		}

		return null;
	}
}
